package com.example.wzviewer.util;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/** 把任意 Uri 转为 ffprobe 可读的路径。
 *  优先使用 /proc/self/fd/<fd>（零拷贝）；若 asset 被压缩无法 openFd，则拷到缓存临时文件。 */
public final class UriToFdPath {
    private UriToFdPath(){}

    public static class FdHandle implements AutoCloseable {
        public final String path; // 交给 ffprobe 的路径
        public final ParcelFileDescriptor pfd; // 需要持有到命令结束
        public final AssetFileDescriptor afd;  // 资产句柄
        public final File tmpFile;             // 资产压缩场景的临时拷贝

        FdHandle(String path, ParcelFileDescriptor pfd, AssetFileDescriptor afd, File tmpFile) {
            this.path = path; this.pfd = pfd; this.afd = afd; this.tmpFile = tmpFile;
        }
        @Override public void close() {
            try { if (afd != null) afd.close(); } catch (Exception ignore) {}
            try { if (pfd != null) pfd.close(); } catch (Exception ignore) {}
            try { if (tmpFile != null) tmpFile.delete(); } catch (Exception ignore) {}
        }
    }

    public static FdHandle toFdPath(Context ctx, Uri uri) throws Exception {
        String scheme = uri.getScheme();
        if ("asset".equalsIgnoreCase(scheme)) {
            String rel = uri.toString().replaceFirst("^asset:///+", "");
            try {
                AssetFileDescriptor afd = ctx.getAssets().openFd(rel);
                ParcelFileDescriptor pfd = afd.getParcelFileDescriptor();
                String path = "/proc/self/fd/" + pfd.getFd();
                return new FdHandle(path, pfd, afd, null);
            } catch (Throwable t) {
                // 某些打包下 asset 被压缩，openFd 失败，则拷贝进缓存文件
                InputStream is = ctx.getAssets().open(rel);
                File tmp = File.createTempFile("ffp_asset_", ".bin", ctx.getCacheDir());
                try (FileOutputStream os = new FileOutputStream(tmp)) {
                    byte[] buf = new byte[8192];
                    int n; while ((n = is.read(buf)) > 0) os.write(buf, 0, n);
                } finally { try { is.close(); } catch (Exception ignore) {} }
                return new FdHandle(tmp.getAbsolutePath(), null, null, tmp);
            }
        } else {
            // content:// 或 file://（或裸路径）
            ParcelFileDescriptor pfd = ctx.getContentResolver().openFileDescriptor(uri, "r");
            String path = "/proc/self/fd/" + pfd.getFd();
            return new FdHandle(path, pfd, null, null);
        }
    }
}
